Skip to content

13B: Notices split into a writer and a presenter - #22

Merged
d4mation merged 3 commits into
mainfrom
13A-notices-split
Aug 20, 2026
Merged

13B: Notices split into a writer and a presenter#22
d4mation merged 3 commits into
mainfrom
13A-notices-split

Conversation

@nikolaystrikhar

@nikolaystrikhar nikolaystrikhar commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What: Notices\Queue splits into Notices\Writer (words a notice, stores it under slug:type, behind the new Writer_Interface) and Notices\Presenter (the activate_plugins gate and the render-then-clear, bound by class name); Absorber::notices() returns the writer and Absorber::render_notices() resolves the presenter.

Usage:

// Reword every notice without touching where they are kept or how they are drawn.
$container->singleton( Writer_Interface::class, My_Notice_Writer::class );

Why this way:

The name was wrong and the class was two jobs. Queue never held the queue — Store does — and it answered both "what does this notice say" and "who may see the pending set, and is it gone once they have". A host already running its own notices library has an opinion about the first and none about the second.

Only the writer earns a contract. Nothing in the library dispatches on how a notice reaches the screen: the all_admin_notices trampoline is the presenter's only caller, so a host that wants none of our rendering takes that callback off rather than binding an implementation that does nothing.

The capability check goes with render-and-clear, not with the markup. It guards the clearing as much as the drawing, so deciding those separately would let a user who may not see the queue destroy it anyway, through a class that never checked.

No behaviour changes. It is a move, which is why it exceeds the usual source-file cap.

Summary by CodeRabbit

  • New Features

    • Added separate notice writing and presentation components.
    • Notices are now rendered only for authorized administrators and cleared after display.
    • Added support for independently customizing notice wording, storage, rendering, and presentation.
  • Documentation

    • Updated architecture, configuration, and notice-rendering documentation to reflect the new notice workflow.
  • Tests

    • Expanded coverage for notice writing, persistence, rendering, permissions, sanitization, and queue handling.

Notices\Queue was two jobs and a wrong name. It never held the queue -- Store
does -- and it answered both "what does this notice say" and "who may see the
pending set, and is it gone once they have". Those change for different reasons,
and a host already running its own notices library has an opinion about the first
and none about the second.

Notices\Writer takes Store and words the notices, behind Writer_Interface, which
is what a host rebinds. Notices\Presenter takes Store and Renderer and does the
render-then-clear, with the activate_plugins gate that gua...(truncated)
@nikolaystrikhar nikolaystrikhar changed the title 13A: Notices split into a writer and a presenter 13B: Notices split into a writer and a presenter Aug 13, 2026
Every new PHP file declares strict_types, so the rule arrives with the file
rather than as a sweep over it afterwards. PR 21 covers everything that already
existed on main.

The three files this branch renames count as new here. Writer, Writer_Interface
and Spy_Writer are new paths that main has never carried, so waiting for the
rename to inherit the declare from the file it came from would leave them
without one for as long as PR 21 is unmerged -- and leave Presenter, added
outright beside them, declaring it already.

@d4mation d4mation left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I'm 100% sold on the name Presenter, but I do agree with the overall split of concerns :)

Base automatically changed from 13-activation to main August 20, 2026 19:21
@d4mation
d4mation merged commit 89caacd into main Aug 20, 2026
5 of 6 checks passed
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Enterprise

Run ID: c7688871-b77a-4d57-99a9-d67c19d1a1e3

📥 Commits

Reviewing files that changed from the base of the PR and between fc47e6e and 957e13d.

📒 Files selected for processing (26)
  • CLAUDE.md
  • docs/configuration.md
  • docs/notices.md
  • src/Absorber.php
  • src/Conflict/Gatekeeper.php
  • src/Conflict/Resolver.php
  • src/Loader.php
  • src/Notices/Contracts/Writer_Interface.php
  • src/Notices/Presenter.php
  • src/Notices/Renderer.php
  • src/Notices/Store.php
  • src/Notices/Writer.php
  • src/Provider.php
  • tests/README.md
  • tests/_support/Spy_Presenter.php
  • tests/_support/Spy_Writer.php
  • tests/unit/AbsorberTest.php
  • tests/unit/Boot/SchedulerTest.php
  • tests/unit/Conflict/ResolverTest.php
  • tests/unit/LoaderTest.php
  • tests/unit/Notices/PresenterTest.php
  • tests/unit/Notices/QueueTest.php
  • tests/unit/Notices/RendererTest.php
  • tests/unit/Notices/StoreTest.php
  • tests/unit/Notices/WriterTest.php
  • tests/unit/ProviderTest.php

📝 Walkthrough

Walkthrough

The notice queue abstraction is split into Writer, Presenter, Store, and Renderer. Container bindings, runtime collaborators, tests, and architecture documentation now use the separated responsibilities.

Changes

Notice architecture

Layer / File(s) Summary
Writer and Presenter components
src/Notices/Contracts/Writer_Interface.php, src/Notices/Writer.php, src/Notices/Presenter.php, src/Notices/Renderer.php, src/Notices/Store.php
Writer_Interface now covers notice writing and persistence. Writer no longer renders notices. Presenter handles capability checks, rendering, and queue clearing.
Container and runtime wiring
src/Absorber.php, src/Provider.php, src/Conflict/Resolver.php, src/Loader.php, src/Conflict/Gatekeeper.php
Runtime accessors and constructors now use Writer_Interface. Provider binds Writer_Interface and Presenter separately.
Validation and architecture documentation
tests/unit/Notices/*, tests/unit/AbsorberTest.php, tests/unit/Boot/SchedulerTest.php, tests/unit/ProviderTest.php, tests/unit/Conflict/ResolverTest.php, tests/unit/LoaderTest.php, tests/_support/*, docs/*, CLAUDE.md, tests/README.md
Tests cover writer persistence and presenter rendering. Spies, examples, and documentation use the new component boundaries.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Absorber
  participant Presenter
  participant Store
  participant Renderer
  Absorber->>Presenter: resolve and call render()
  Presenter->>Store: read queued notices
  Presenter->>Renderer: render valid notices
  Presenter->>Store: clear queue after rendering
``

</details>

<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

<details>
<summary>📝 Generate docstrings</summary>

- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch

</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit unit tests in branch `13A-notices-split`

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---




<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>

<!-- tips_end -->
Loading

@d4mation
d4mation deleted the 13A-notices-split branch August 20, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants